home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / MPW / gzip 1.2.2 / cextras-1.0 / dirent.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-07-11  |  4.7 KB  |  240 lines  |  [TEXT/MPS ]

  1. /*
  2.     dirent.c -- file system independant directory access routines for MacOS
  3.  
  4.     Copyright (c) 1993 Anthony C. Ard.
  5.  
  6.     This program is free software; you can redistribute it and/or
  7.     modifiy it under the terms of the GNU General Public License
  8.     as published by the Free Software Foundation; either version 2
  9.     of the License, or (at your option) any later version.
  10.     
  11.     This program is distributed in the hope that it will be useful,
  12.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14.     GNU General Public License for more details.
  15.     
  16.     You should have received a copy of the GNU General Public License
  17.     along with this program; if not, write to the Free Software
  18.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. */
  20.  
  21. #include <string.h>
  22. #include <strings.h>
  23. #include <plstringfuncs.h>
  24. #include <files.h>
  25. #include <errors.h>
  26. #include <errno.h>
  27. #include <stdlib.h>
  28. #include "sys_types.h"
  29. #include "dirent.h"
  30.  
  31. typedef void *pointer;
  32.  
  33. #ifndef NULL
  34. #define    NULL    0
  35. #endif
  36.  
  37. static int bit( unsigned long op, unsigned long bitnum );
  38. #define bit(op,bitnum) (int)(op >> bitnum & 0x01UL)
  39.  
  40. /*
  41.     closedir -- close a directory stream
  42. */
  43.  
  44. int closedir( register DIR *dirp )
  45. {
  46.     if( dirp == NULL || dirp->dd_buf == NULL ) {
  47.         errno = EFAULT;
  48.         return -1;        /* invalid pointer */
  49.     }
  50.  
  51.     free( (pointer)dirp->dd_buf );
  52.     free( (pointer)dirp );
  53.     return NULL;
  54. }
  55.  
  56. /*
  57.     opendir -- open a directory stream
  58. */
  59.  
  60. DIR *opendir( char *dirname )
  61. {
  62.     register DIR    *dirp;
  63.     int                err;
  64.     Str255            fname;
  65.     CInfoPBRec        myInfo;
  66.     
  67.     strcpy( fname, dirname );
  68.  
  69. #ifdef DEBUG    
  70.     printf( "# opendir: fname = %s\n", fname );
  71. #endif DEBUG
  72.  
  73.     c2pstr( fname );
  74.  
  75.     myInfo.hFileInfo.ioVRefNum = 0;
  76.     myInfo.hFileInfo.ioFDirIndex = 0;
  77.     myInfo.hFileInfo.ioDirID = 0;
  78.     myInfo.hFileInfo.ioNamePtr = fname;
  79.  
  80.     err = PBGetCatInfoSync( &myInfo );
  81.     if( err != noErr ) {
  82.         switch( err ) {
  83.             case bdNamErr:
  84.                 errno = EINVAL;
  85.                 break;
  86.             case dirNFErr:
  87.                 errno = ENOENT;
  88.                 break;
  89.             case fnfErr:
  90.                 errno = ENOENT;
  91.                 break;
  92.             case ioErr:
  93.                 errno = EIO;
  94.                 break;
  95.             case nsvErr:
  96.                 errno = ENXIO;
  97.                 break;
  98.             case paramErr:
  99.                 errno = EINVAL;
  100.                 break;
  101.         }
  102.         return NULL;
  103.     }
  104.  
  105.     if( !bit( myInfo.hFileInfo.ioFlAttrib, 4 ) ) {    /* Check for directory */
  106.         errno = ENOTDIR;
  107.         return NULL;        /* not a directory */
  108.     }
  109.  
  110.     if( (dirp = (DIR *)malloc( sizeof(DIR) )) == NULL
  111.         || (dirp->dd_buf = (char *)malloc( (unsigned)DIRBUF )) == NULL ) {
  112.         register int serrno = errno;
  113.         /* errno set to ENOMEM by sbrk() */
  114.  
  115.         if ( dirp != NULL )
  116.             free( (pointer)dirp );
  117.  
  118.         errno = serrno;
  119.         return NULL;
  120.         }
  121.  
  122.     dirp->dd_fd = myInfo.dirInfo.ioDrDirID;
  123.     dirp->dd_loc = 1;        /* Start of first entry in directory */
  124.     dirp->dd_size = myInfo.dirInfo.ioDrNmFls;   /* Max number of entries */
  125.  
  126.     return dirp;
  127. }
  128.  
  129. /*
  130.     readdir -- read next entry from a directory stream
  131. */
  132.  
  133. struct dirent *readdir( register DIR *dirp )
  134. {
  135.     register struct dirent    *dp;
  136.  
  137.     int            err;
  138.     Str255        fname;
  139.     CInfoPBRec    myInfo;
  140.  
  141.     if( dirp == NULL || dirp->dd_buf == NULL ) {
  142.         errno = EFAULT;
  143.         return NULL;        /* invalid pointer */
  144.     }
  145.  
  146.     myInfo.hFileInfo.ioNamePtr = fname;
  147.  
  148.     do {
  149.         myInfo.hFileInfo.ioVRefNum = 0;
  150.         myInfo.hFileInfo.ioFDirIndex = dirp->dd_loc;
  151.         myInfo.hFileInfo.ioDirID = dirp->dd_fd;
  152.         fname[0] = 0;
  153.     
  154.         err = PBGetCatInfoSync( &myInfo );
  155.         if( err != noErr ) {
  156.             switch( err ) {
  157.                 case bdNamErr:
  158.                     errno = EINVAL;
  159.                     break;
  160.                 case dirNFErr:
  161.                     errno = ENOENT;
  162.                     break;
  163.                 case fnfErr:
  164.                     errno = ENOENT;
  165.                     break;
  166.                 case ioErr:
  167.                     errno = EIO;
  168.                     break;
  169.                 case nsvErr:
  170.                     errno = ENXIO;
  171.                     break;
  172.                 case paramErr:
  173.                     errno = EINVAL;
  174.                     break;
  175.             }
  176.             return NULL;
  177.         }
  178.     
  179.         dp = (struct dirent *)dirp->dd_buf;
  180.  
  181.         dp->d_ino = myInfo.hFileInfo.ioDirID;
  182.         dp->d_off = dirp->dd_loc;
  183.         dp->d_reclen = 1;
  184.         PLstrcpy( dp->d_name, myInfo.hFileInfo.ioNamePtr );
  185.         p2cstr( dp->d_name );
  186.         dirp->dd_loc++;
  187.  
  188.     } while( bit( myInfo.hFileInfo.ioFlAttrib, 4 ) ); /* Skip subdirectories */
  189.     
  190.     return dp;
  191. }
  192.  
  193. /*
  194.     rewinddir -- rewind a directory stream
  195. */
  196.  
  197. void rewinddir( register DIR *dirp )
  198. {
  199.     if( dirp == NULL || dirp->dd_buf == NULL ) {
  200.         errno = EFAULT;
  201.         return;            /* invalid pointer */
  202.     }
  203.  
  204.     dirp->dd_loc = 1;    /* First entry in directory */
  205. }
  206.  
  207. /*
  208.     seekdir -- reposition a directory stream
  209. */
  210.  
  211. void seekdir( register DIR *dirp, register off_t loc )
  212. {
  213.     if( dirp == NULL || dirp->dd_buf == NULL ) {
  214.         errno = EFAULT;
  215.         return;            /* invalid pointer */
  216.     }
  217.  
  218.     if ( loc > dirp->dd_size ) {
  219.         errno = EINVAL;
  220.         return;            /* invalid argument */
  221.     }
  222.  
  223.     if( loc == 0 ) loc = 1;    
  224.     dirp->dd_loc = loc;
  225. }
  226.  
  227. /*
  228.     telldir -- report directory stream position
  229. */
  230.  
  231. off_t telldir( DIR *dirp )
  232. {
  233.     if( dirp == NULL || dirp->dd_buf == NULL ) {
  234.         errno = EFAULT;
  235.         return -1;        /* invalid pointer */
  236.     }
  237.  
  238.     return dirp->dd_loc;
  239. }
  240.